package com.oyjd.ybx.fw.util;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 * 对称加解密
 * 
 * @author 欧建东
 * @email oyjd@163.com
 * 
 */
public class SecurityUtil2 {
	/*
	 * 对称加密
	 */
	public static void secretEncrypt1() throws Exception {
		// 使用Cipher的实例
		Cipher cipher = Cipher.getInstance("AES");

		// 得到加密的钥匙
		SecretKey key = KeyGenerator.getInstance("AES").generateKey();

		// 初始化加密操作,传递加密的钥匙
		cipher.init(Cipher.ENCRYPT_MODE, key);

		// 将加密的钥匙写入secretKey.key文件中
		FileOutputStream fosKey = new FileOutputStream("secretKey.key");
		ObjectOutputStream oosSecretKey = new ObjectOutputStream(fosKey);
		oosSecretKey.writeObject(key);
		oosSecretKey.close();
		fosKey.close();

		// 将加密的内容传递进去，返回加密后的二进制数据
		byte[] results = cipher.doFinal("哈哈哈哈哈".getBytes());

		// 将加密后的二进制数据写入到secretContent.dat文件中
		FileOutputStream fosData = new FileOutputStream("secretContent.dat");
		fosData.write(results);
		fosData.close();
	}

	/*
	 * 对称解密
	 */
	public static void secretDecrypt1() throws Exception {
		Cipher cipher = Cipher.getInstance("AES");

		// 获取文件中的key进行解密
		FileInputStream fisKey = new FileInputStream("secretKey.key");
		ObjectInputStream oisKey = new ObjectInputStream(fisKey);
		Key key = (Key) oisKey.readObject();
		oisKey.close();
		fisKey.close();

		// 初始化解密操作,传递加密的钥匙
		cipher.init(Cipher.DECRYPT_MODE, key);

		// 获取文件中的二进制数据
		FileInputStream fisDat = new FileInputStream("secretContent.dat");
		// 获取数据第一种方式
		byte[] src = new byte[fisDat.available()];
		int len = fisDat.read(src);
		int total = 0;
		while (total < src.length) {
			total += len;
			len = fisDat.read(src, total, src.length - total);
		}
		// 执行解密
		byte[] result = cipher.doFinal(src);
		fisDat.close();
		System.out.println(new String(result));

	}

	/*
	 * 基于口令的对称加密
	 */
	public static void secretEncrypt() throws Exception {
		// 实例化工具
		Cipher cipher2 = Cipher.getInstance("PBEWithMD5AndDES");

		// 使用该工具将基于密码的形式生成Key
		SecretKey key2 = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray()));
		PBEParameterSpec parameterspec = new PBEParameterSpec(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, 1000);

		// 初始化加密操作，同时传递加密的算法
		cipher2.init(Cipher.ENCRYPT_MODE, key2, parameterspec);

		// 将要加密的数据传递进去，返回加密后的数据
		byte[] results = cipher2.doFinal("哈哈哈哈哈".getBytes());

		// 将加密后的数据写入到文件中
		FileOutputStream fosData = new FileOutputStream("zxx.dat");
		fosData.write(results);
		fosData.close();
	}

	/*
	 * 基于口令的对称解密
	 */
	public static void secretDecrypt() throws Exception {
		Cipher cipher2 = Cipher.getInstance("PBEWithMD5AndDES");
		SecretKey key2 = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray()));
		PBEParameterSpec parameterspec = new PBEParameterSpec(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, 1000);
		cipher2.init(Cipher.DECRYPT_MODE, key2, parameterspec);
		FileInputStream fisDat = new FileInputStream("zxx.dat");
		byte[] src = new byte[fisDat.available()];
		int len = fisDat.read(src);
		int total = 0;
		while (total < src.length) {
			total += len;
			len = fisDat.read(src, total, src.length - total);
		}
		byte[] result = cipher2.doFinal(src);
		fisDat.close();
		System.out.println(new String(result));
	}

}
